# -*- encoding: utf-8 -*-
#
# BE SURE YOU TEST ON AN EMPTY TABLE!
#

import unittest
import settings_in_db


class TestSettingsInDB(unittest.TestCase):
	
	#--- Helper
	def setUp(self):
		self.s = settings_in_db.Settings()
		self._clean_up()

	def tearDown(self):
		self._clean_up()
		settings_in_db.db.Session.remove()

	def _clean_up(self):
		'''Delete the test entries from the database.'''
		if 'test_1' in self.s:
			del self.s['test_1']
		if 'test_2' in self.s:
			del self.s['test_2']
		if 'test_3' in self.s:
			del self.s['test_3']
	
	#--- Getter, Setter, Deleter
	def test_storing_integer(self):
		self.s['test_1'] = 1
		self.assertEquals(1, self.s['test_1'])
		self.s['test_2'] = 12345
		self.assertEquals(12345, self.s['test_2'])
		
	def test_storing_float(self):
		self.s['test_1'] = 1.2345
		self.assertEquals(1.2345, self.s['test_1'])
		self.s['test_2'] = 432.56
		self.assertEquals(432.56, self.s['test_2'])
	
	def test_storing_string(self):
		self.s['test_1'] = 'tEsTStrinG'
		self.assertEquals('tEsTStrinG', self.s['test_1'])
		self.s['test_2'] = '$&/(){¬ŋŧ¶đđ¼v '
		self.assertEquals('$&/(){¬ŋŧ¶đđ¼v ', self.s['test_2'])
		
	def test_storing_boolean(self):
		self.s['test_1'] = False
		self.assertFalse(self.s['test_1'])
		self.s['test_2'] = True
		self.assertTrue(self.s['test_2'])

	def test_storing_none(self):
		self.s['test_1'] = None
		self.assertEquals(None, self.s['test_1'])
		
	def test_get_value_neg(self):
		'''test_get_value_neg: Key must be a string and the setting must
		exist.'''
		self.assertRaises(TypeError, self.s.__getitem__, 1)
		self.assertRaises(TypeError, self.s.__getitem__, 1.9)
		self.assertRaises(TypeError, self.s.__getitem__, (1,2))
		self.assertRaises(KeyError, self.s.__getitem__, 'test_1')
		self.assertRaises(KeyError, self.s.__getitem__, 'test_2')
		self.assertRaises(KeyError, self.s.__getitem__, 'test_3')
	
	def test_set_value_neg(self):
		'''test_set_value_neg: Key must be a string and value must be one of
		str, int, float or None.'''
		self.assertRaises(TypeError, self.s.__setitem__, 1, 1)
		self.assertRaises(TypeError, self.s.__setitem__, 'test_1', ())
		self.assertRaises(TypeError, self.s.__setitem__, 'test_2', {})
		self.assertRaises(TypeError, self.s.__setitem__, 'test_3', [])
		
	def test_contains(self):
		self.s['test_1'] = None
		self.assertTrue('test_1' in self.s)
		self.s['test_2'] = 'foo'
		self.assertTrue('test_2' in self.s)
		
	def test_contains_neg(self):
		'''test_contains_neg: key must be a string.'''
		self.assertRaises(TypeError, self.s.__contains__, 1)
		self.assertRaises(TypeError, self.s.__contains__, 1.9)
		self.assertRaises(TypeError, self.s.__contains__, (1,2))
		self.assertFalse('test_1' in self.s)
		self.assertFalse('test_2' in self.s)
		self.assertFalse('test_3' in self.s)
		
	def test_deleting(self):
		self.s['test_1'] = 1
		self.assertTrue('test_1' in self.s)
		self.s['test_2'] = 12345
		self.assertTrue('test_2' in self.s)
		
		del self.s['test_1']
		self.assertFalse('test_1' in self.s)
		del self.s['test_2']
		self.assertFalse('test_2' in self.s)
		
	def test_deleting_neg(self):
		'''test_del_item_neg: key must be a string and setting must exist.'''
		self.assertRaises(TypeError, self.s.__delitem__, 1)
		self.assertRaises(TypeError, self.s.__delitem__, 1.9)
		self.assertRaises(TypeError, self.s.__delitem__, (1,2))
		self.assertRaises(KeyError, self.s.__delitem__, 'test_1')
		self.assertRaises(KeyError, self.s.__delitem__, 'test_2')
		self.assertRaises(KeyError, self.s.__delitem__, 'test_3')
	
	#--- Length
	def test_length(self):
		self.assertEqual(0, len(self.s))
		self.s['test_1'] = None
		self.assertEqual(1, len(self.s))
		self.s['test_2'] = 12345
		self.assertEqual(2, len(self.s))
		del self.s['test_1']
		self.assertEqual(1, len(self.s))
		del self.s['test_2']
		self.assertEqual(0, len(self.s))
		
		self.s['test_1'] = None
		self.s['test_2'] = 12345
		self.s['test_3'] = 'abc'
		self.assertEqual(3, len(self.s))
		self.s.clear()
		self.assertEqual(0, len(self.s))

	
	#--- Iterators
	def test_iterator(self):
		self.s['test_1'] = 1
		self.s['test_2'] = 2
		self.s['test_3'] = 3
		
		keys = {
			1 : 'test_1',
			2 : 'test_2',
			3 : 'test_3'
		}
		
		i = 1
		for key in self.s:
			self.assertEquals(keys[i], key)
			i += 1

	def test_iter_items(self):
		self.s['test_1'] = 1
		self.s['test_2'] = 2
		self.s['test_3'] = 3
		
		items = {
			1 : ('test_1', 1),
			2 : ('test_2', 2),
			3 : ('test_3', 3)
		}
		
		i = 1
		for item in self.s.iteritems():
			self.assertEquals(items[i], item)
			i += 1
	
	
	#--- Dictonary specific stuff
	def test_keys(self):
		self.assertEquals([], self.s.keys())
		self.s['test_1'] = 1
		self.assertTrue('test_1' in self.s.keys())
		self.s['test_2'] = 1.234
		self.assertTrue('test_2' in self.s.keys() \
						and 'test_1' in self.s.keys())
		self.s['test_3'] = 'abc'
		self.assertTrue('test_3' in self.s.keys() \
						and 'test_2' in self.s.keys() \
						and 'test_1' in self.s.keys())
		
	def test_keys_neg(self):
		self.assertFalse('test_1' in self.s.keys())
		self.assertFalse('test_2' in self.s.keys())
		
	def test_has_key(self):
		self.s['test_1'] = 1
		self.assertTrue(self.s.has_key('test_1'))
		self.s['test_2'] = 'abc'
		self.assertTrue(self.s.has_key('test_2'))
		
	def test_has_key_neg(self):
		'''test_has_key_neg: key must be a string and setting must exist.'''
		self.assertRaises(TypeError, self.s.has_key, 1)
		self.assertRaises(TypeError, self.s.has_key, 1.9)
		self.assertRaises(TypeError, self.s.has_key, (1,2))
		self.assertFalse(self.s.has_key('test_1'))
		self.assertFalse(self.s.has_key('test_2'))
		self.assertFalse(self.s.has_key('test_3'))


if __name__ == "__main__":
	unittest.main()